/**
 * Static class that writes log messages to a log file.
 */
package sharedUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

public class Logger {
	//@author A0101655N
	private static File f;
	private static FileWriter fw;
	private static BufferedWriter bw;
	
	public static boolean isInit = false;
	
	//@author A0097758E
	/**
	 * Initializes FileWriter and BufferedWriter
	 * 
	 * @return True when both FileWriter and BufferedWriter are initialized successfully. False otherwise.
	 */
	private static boolean initLogger() {
		if(isInit) {
			return isInit;
		}
		
		f = new File(Constants.DEFAULT_LOG_FILE_LOC);

		/**
		 * FileWriter second argument is for append if its true then FileWritter will
		 * write bytes at the end of File (append) rather than beginning of file
		 */
		
		try{ // to create bw object
			fw = new FileWriter(f.getAbsoluteFile(), true);
			bw = new BufferedWriter(fw);	
		} catch(IOException ioe) {
			System.err.println("[EXCEPTION, Logger] initLogger(): IOException encountered while creating BW/FW.");
			ioe.printStackTrace();
			System.out.println();
			
			return false;
		}
		
		isInit = true;
		return isInit;
	}
	
	//@author A0101655N
	/**
	 * Logs required information to Constants.DEFAULT_LOG_FILE_LOC
	 * 
	 * @param message - message of the log
	 * @param className - className of calling function
	 * @param methodName - methodName of calling function
	 */
	synchronized public static void log(String message, String className, String methodName) {
		if(!Constants.isLoggingEnabled) {
			return;
		}
		
		/**
		 * Check if this has been initiated
		 * If it has been, continue. If not, do nothing.
		 */	
		
		initLogger();
		
		try {
			if (isInit) {
				System.out.println("Writing... "+className+", "+methodName);
				/**
				 * Append to end of file in the following format
				 * [TIMESTAMP][CLASSNAME][METHODNAME]: MESSAGE\n
				 */
				
				bw.append("[" + new Date() + "]" + "[" + className + "]" + "[" + methodName + "]" + ": " + message);
				bw.newLine();
			}
		} catch(IOException ioe) {
			System.err.println("[EXCEPTION, Logger] log(): IOException encountered while writing.");
			ioe.printStackTrace();
			System.out.println();
		}
		
		close();
	}
	
	//@author A0097758E
	/**
	 * Closes both FileWriter and BufferedWriter, allowing them flush the I/O 
	 * and push its contents into the File.
	 */
	private static void close() {
		if(!isInit) {
			return;
		}
		
		try{
			if(bw != null) {
				bw.close();
			}
			
			if(fw != null) {
				fw.close();
			}
			
		} catch(Exception e) {
			System.err.println("[EXCEPTION, Logger] close(): Exception encountered when trying to close BW/FW.");
			e.printStackTrace();
			System.out.println();
		}
		
		isInit = false;
	}
}